<template>
  <template v-if="loaded">
    <ProForm
      ref="formRef"
      :model="formState"
      :items="items"
      :disabled="readonly"
      :onValuesChange="onValuesChange"
      :formColLayout="formColLayout()"
      :requiredMark="!readonly"
      class="pro-form-modal"
      v-bind="formProps"
    >
    </ProForm>
    <FooterButtons
      :formState="formState"
      :formRef="formRef"
      v-model:readonly="readonly"
      :serviceApi="_updateDeviceConfig"
      @refresh="refresh"
      :fastConfig="fastConfig"
    />
  </template>
</template>

<script setup lang="tsx">
import { computed, nextTick, ref, shallowRef } from 'vue';
import { ProForm, ProFormProps } from '@/components/ProForm';
import { ItemProps } from '@/components/ProForm/interface';
import {
  getDeviceConfig,
  getEthernetConfig,
  getVideoConfig,
  updateDeviceConfig,
  updateEthernetConfig,
  updateVideoConfig,
} from '@/api/device';
import FooterButtons from './FooterButtons.vue';

defineOptions({
  name: 'Device',
});

interface Props {
  pageData: any;
  readonly?: any;
  fastConfig?: boolean;
}
const props = defineProps<Props>();
const loaded = ref(false);
const readonly = ref(props.readonly ?? true);
const formRef = shallowRef();
const formState = ref<Record<string, any>>({});

const column = 3;
const formColLayout = () => {
  const num = 24 / column;
  return { xs: num, sm: num, md: num, lg: num };
};
const formProps = computed<ProFormProps>(() => {
  return {
    labelCol: { span: 9 },
    wrapperCol: { span: 20 },
  };
});
const onValuesChange = (
  values: Record<string, any>,
  state: Record<string, any>,
) => {
  formState.value = {
    ...formState.value,
    ...state,
  };
};
const refresh = () => {
  loaded.value = false;
  nextTick(() => {
    loaded.value = true;
  });
};
const itemObj = (
  label: string,
  type: any,
  field: string,
  required: boolean = false,
  props?: any,
  layout?: any,
  rules: any = [],
): ItemProps => {
  return {
    label,
    type,
    field,
    props: {
      placeholder: `请${type == 'input' ? '输入' : '选择'}${label}`,
      allowClear: false,
      ...props,
    },
    rules: [
      {
        required,
        message: `请${type == 'input' ? '输入' : '选择'}${label}`,
        trigger: 'blur',
      },
      ...rules,
    ],
    ...layout,
  };
};
const itemRender = (title: string): ItemProps => {
  return {
    label: { title },
    type: 'input',
    field: 'h5',
    formItemRender() {
      return <h5 class='h5'>{title}</h5>;
    },
  };
};
const radioOptions = [
  { value: '0', label: '关闭' },
  { value: '1', label: '开启' },
];
const desktopTerminal = props.pageData.deviceType == '3';

const protobufVersion = Number(props.pageData.protobufVersion);

const items = computed<ProFormProps['items']>(() => [
  itemRender('服务配置'),
  itemObj('首页图片循环', 'radio', 'isBannerLoop', true, {
    options: radioOptions,
  }),
  itemObj('首页图片循环间隔', 'input', 'bannerLoopTime', true, {
    addonAfter: '秒',
  }),
  itemObj('自动清理', 'radio', 'isAutoClean', true, {
    options: radioOptions,
  }),
  itemObj('天气更新间隔', 'input', 'weatherIntervalTime', true, {
    addonAfter: '分',
  }),
  itemObj('预警资料保存份数', 'input', 'warningFileCount', true),
  itemObj('日志保存天数', 'input', 'logsFileDay', true),
  ...(!desktopTerminal
    ? [
        itemObj('首页避难所显示', 'radio', 'isOpenShelter', false, {
          options: radioOptions,
        }),
        itemObj('避难所展示时间', 'input', 'shelterShowTime', false, {
          addonAfter: '分',
        }),
      ]
    : []),
  itemObj('', null, '', false),
  ...(protobufVersion > 1
    ? [
        itemObj('欢迎图片循环', 'radio', 'isWelcomeLoop', false, {
          options: radioOptions,
        }),
        itemObj('欢迎图片循环间隔', 'input', 'welcomeLoopTime', false, {
          addonAfter: '秒',
        }),
      ]
    : []),
  itemRender('视频配置'),
  itemObj('录制分辨率', 'select', 'videoResolution', true, {
    options: [
      { value: '0', label: '480p' },
      { value: '1', label: '720p' },
    ],
  }),
  ...(!desktopTerminal
    ? [
        itemObj('烈度触发采集视频', 'radio', 'isOpenVideoRecord', true, {
          options: radioOptions,
        }),
        itemObj('触发采集烈度', 'input', 'recordIntensity', true),
        itemObj('采集时间', 'input', 'recordDelayTime', true, {
          addonAfter: '秒',
        }),
        ...(props.pageData.deviceConfigsJson
          ? []
          : [
              itemRender('以太网'),
              itemObj('IP模式', 'radio', 'ethernetMode', false, {
                options: [
                  { value: '0', label: '动态模式' },
                  { value: '1', label: '静态模式' },
                ],
              }),
              itemObj('IP地址', 'input', 'ethernetIpAddress', false),
              itemObj('子网掩码', 'input', 'ethernetNetmask', false),
              itemObj('网关地址', 'input', 'ethernetGateway', false),
              itemObj('首选DNS地址', 'input', 'ethernetDns1', false),
              itemObj('备选DNS地址', 'input', 'ethernetDns2', false),
            ]),
      ]
    : []),
]);

props.pageData.deviceConfigsJson
  ? (() => {
      formState.value = JSON.parse(props.pageData.deviceConfigsJson);
      formState.value = Object.assign(
        formState.value,
        JSON.parse(props.pageData.videoConfigsJson),
      );
      loaded.value = true;
    })()
  : Promise.all([
      getDeviceConfig(props.pageData.code),
      getEthernetConfig(props.pageData.code),
      getVideoConfig(props.pageData.code),
    ]).then((res: any) => {
      res.forEach((r: any) => {
        formState.value = { ...formState.value, ...r.data };
      });
      formState.value.code = props.pageData.code;
      loaded.value = true;
    });

const _updateDeviceConfig = async (params: any) => {
  await Promise.all([
    updateDeviceConfig(params),
    updateEthernetConfig(params),
    updateVideoConfig(params),
  ]);
};

defineExpose({
  async save() {
    const data = await formRef.value.validate();
    props.pageData.deviceConfigsJson = JSON.stringify(data);
    const {
      isOpenVideoRecord,
      recordDelayTime,
      recordIntensity,
      videoResolution,
    } = data;
    props.pageData.videoConfigsJson = JSON.stringify({
      isOpenVideoRecord,
      recordDelayTime,
      recordIntensity,
      videoResolution,
    });
  },
});
</script>
